#pragma once

#include <functional>
#include <sys/epoll.h>
#include <iostream>

using namespace std;

class EventLoop;

class Channel {
public:
    typedef function<void()> EventCallback;

    Channel (EventLoop* loop, int fd);
    ~Channel();

    void handleEvent();
    // 设置回调函数
    void setReadCallback(const EventCallback& cb) { readCallback_ = cb; }
    void setWriteCallback(const EventCallback& cb) { writeCallback_ = cb; }
    void setErrorCallback(const EventCallback& cb) { errorCallback_ = cb; }
    void setCloseCallback(const EventCallback& cb) { closeCallback_ = cb; }
    
    int fd() const { return fd_; }
    int events() const { return events_; }
    void set_revents(int revt) { revents_ = revt; } // 设置返回活动事件类型
    bool isNoneEvent() const { return events_ == 0; }

    // 注册读写事件
    void enableReading() { events_ |= EPOLLIN | EPOLLET; update(); }
    void enableWriting() { events_ |= EPOLLOUT | EPOLLET; update(); }
    void disableWriting() { events_ &= ~EPOLLOUT; update(); }
    void disableAll() { events_ = 0; update(); }
    bool isWriting() const { return events_ & EPOLLOUT; }
    bool isReading() const { return events_ & EPOLLIN; }

    int index() { return index_; }
    void set_index(int idx) { index_ = idx; }

    EventLoop* ownerLoop() { return loop_; }
    
    void remove();

    void destruct() { isDesturct_ = true; }
    bool hasDestruct() { return isDesturct_; }

private:
    void update();
    
    EventLoop* loop_;

    const int fd_;
    
    int events_;    // 关注的事件
    int revents_;   // 返回活动事件
    int index_; // used by Poller.

    bool eventHandling_;

    EventCallback readCallback_;
    EventCallback writeCallback_;
    EventCallback errorCallback_;
    EventCallback closeCallback_;

    bool isDesturct_;
};